Implement GpioDriver on Pca95x4 for GpioController access#2581
Conversation
|
@copilot resolve the merge conflicts in this pull request |
There was a problem hiding this comment.
Pull request overview
This PR upgrades the Pca95x4 binding from register-only access to a first-class GpioDriver implementation so the expander’s pins can be used through System.Device.Gpio’s standard GpioController abstraction, aligning it with other I/O expander bindings in this repo.
Changes:
- Make
Pca95x4derive fromGpioDriverand implement the required GPIO driver members by mapping them to the expander’s registers. - Add a new xUnit test project validating pin mode changes and read/write/toggle behavior via
GpioController, plus a regression check for the existing register API. - Update the sample and README to document and demonstrate
GpioControllerusage, and update the device solution to include the new test project.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/devices/Pca95x4/Pca95x4.cs | Implements GpioDriver members over the existing register helpers and moves disposal into Dispose(bool). |
| src/devices/Pca95x4/tests/Pca95x4Test.cs | Adds unit tests using an in-memory I2cDevice mock to validate controller-style GPIO behavior. |
| src/devices/Pca95x4/tests/Pca95x4.Tests.csproj | Introduces a new test project referencing the device project. |
| src/devices/Pca95x4/samples/Program.cs | Adds a UseAsGpioController usage example (commented out by default). |
| src/devices/Pca95x4/README.md | Documents how to use Pca95x4 via GpioController. |
| src/devices/Pca95x4/Pca95x4.sln | Adds the new test project (and solution folder) to the device solution. |
Suppressed comments (1)
src/devices/Pca95x4/Pca95x4.sln:68
- The new "tests" solution folder is created, but the new Pca95x4.Tests project is not nested under it in the NestedProjects section, so it will appear at the solution root and the folder will be empty. Add the missing mapping so the tests project is grouped correctly.
GlobalSection(NestedProjects) = preSolution
{3532B861-27D2-4866-84C1-EC19AFB0EEF1} = {E36E35C8-844F-48E9-AFB8-10A1D40AEC51}
EndGlobalSection
…odriver-for-pca95x4 # Conflicts: # src/devices/Pca95x4/Pca95x4.cs Co-authored-by: krwq <660048+krwq@users.noreply.github.com>
| } | ||
|
|
||
| /// <inheritdoc/> | ||
| protected override int PinCount => PinCountConst; |
There was a problem hiding this comment.
local Copilot comment:
🟠 Toggle misbehaves when input polarity inversion is enabled (major, new bug)
The PR doesn't override Toggle, so GpioDriver's default Toggle(pin) = Write(pin, !Read(pin)) runs. Read goes to InputPort, which the PCA95x4 datasheet defines to be affected by the PolarityInversion register. If a user has enabled polarity inversion (via the existing public InvertInputRegisterPolarity API) and then calls controller.Toggle(pin) on an output, the driver reads the inverted value and writes the same latch value back — Toggle silently becomes a no-op. Override Toggle to read/flip the OutputPort latch directly (mirrors what Pcx857x does with its cached _pinValueBits).
Pca95x4is an 8-bit I2C IO expander that only exposed register-level access, so its pins couldn't be used through the standard GPIO abstraction. This makesPca95x4derive fromGpioDriver, consistent with thePcx857xandTca955xbindings.Users can now drive the expander pins through a
GpioController:Changes
Pca95x4.cs— Derives fromGpioDriver; implements the driver members (PinCount, open/close,Set/GetPinMode,IsPinModeSupported,Read,Write) by mapping onto theConfiguration/InputPort/OutputPortregisters via the existingReadBit/WriteBithelpers. Event-based members throwNotImplementedExceptionwith an explanatory message (mirrorsPcx857x). Disposal is moved into an override ofDispose(bool). The existing register-level public API is unchanged.tests/— New xUnit project covering pin modes, read/write/toggle throughGpioController(backed by an in-memory register mock), and a regression check on the register API.samples/Program.cs— Adds aUseAsGpioControllerexample.README.md— DocumentsGpioControllerusage.Notes
VirtualGpioController/VirtualGpioPinremap pins from an existing controller and don't supply the hardware driver, so they aren't a substitute here; they can wrap this driver if pin remapping is wanted.Configurationbit is an input, a cleared bit is an output.